//=============================================================================
// STFWeapon - adds differential player/station damage and anti superweapon ammo regen
//=============================================================================
class TFWeapon extends Weapon
    abstract
    DependsOn(RPGStatsInv)
	config(UT2004RPG)
	HideDropDown
	CacheExempt;

var bool bDoAmmoRegen;
var float StationDmgModifier, SkillCost;
var float AmmoRegenAmount[2];
var Weapon ModifiedWeapon;
var Material ModifierOverlay;
var int Modifier, MinModifier, MaxModifier; // +1, +2, -1, -2, etc
var float AIRatingBonus;
var localized string PrefixPos, PostfixPos, PrefixNeg, PostfixNeg;
var bool bCanHaveZeroModifier;
var bool bIdentified;
var int References; //number of UT2004RPG actors referencing this actor
var int SniperZoomMode; //sniper zoom hack
var RPGStatsInv HolderStatsInv;
var int LastAmmoChargePrimary;
//see GiveTo() for the miracle that goes with this
struct ChaosAmmoTypeStructClone
{
	var class<Ammunition> AmmoClass;
	var class<WeaponAttachment> Attachment;
	var class<Pickup> Pickup;
	var bool bSuperAmmoLimit;
};
var array<ChaosAmmoTypeStructClone> ChaosAmmoTypes;


simulated function PostBeginPlay()
{
    local int i;
    super.PostBeginPlay();
    ModifiedWeapon=self;
    for(i=0;i<ArrayCount(FireMode);i++)
    {
        if(InstantFire(FireMode[i])!=none && class<WeaponDamageType>(InstantFire(FireMode[i]).DamageType) != none)
        {
            class<WeaponDamageType>(InstantFire(FireMode[i]).DamageType).default.WeaponClass=self.class;
        }
        else if(ProjectileFire(FireMode[i])!=none && ProjectileFire(FireMode[i]).ProjectileClass!=none && class<WeaponDamageType>(ProjectileFire(FireMode[i]).ProjectileClass.default.MyDamageType)!=none)
        {
            class<WeaponDamageType>(ProjectileFire(FireMode[i]).ProjectileClass.default.MyDamageType).default.WeaponClass=self.class;
        }
 //       else if(TFWBFire(FireMode[i])!=none
    }
}

replication
{
	reliable if (bNetOwner && bNetDirty && Role == ROLE_Authority)
		ModifiedWeapon, Modifier, bIdentified;
}

//RPG functions

static function bool AllowedFor(class<Weapon> Weapon, Pawn Other)
{
	return true;
}

function Generate(tfweapon ForcedWeapon)
{
	local int Count;

	if (ForcedWeapon != None)
		Modifier = ForcedWeapon.Modifier;
	else if (MaxModifier != 0 || MinModifier != 0)
	{
		do
		{
			Modifier = Rand(MaxModifier+1-MinModifier) + MinModifier;
			Count++;
		} until (Modifier != 0 || bCanHaveZeroModifier || Count > 1000)
	}
}

function SetModifiedWeapon(Weapon w, bool bIdentify)
{
	if (w == None)
	{
		Destroy();
		return;
	}
	ModifiedWeapon = self;
	SetWeaponInfo();
	if (bIdentify)
	{
		Instigator = None; //don't want to send an identify message to anyone here
		Identify();
	}
}

simulated function SetWeaponInfo()
{
    local int x;
	for (x = 0; x < NUM_FIRE_MODES; x++)
	{
		if ( FireMode[x].IsA('SniperZoom') || FireMode[x].IsA('PainterZoom') || FireMode[x].IsA('CUTSRZoom')
		     || FireMode[x].IsA('HeliosZoom') || FireMode[x].IsA('LongrifleZoom') || FireMode[x].IsA('PICZoom') )
			SniperZoomMode = x;
	}
}

function Identify()
{
	if (Modifier == 0 && !bCanHaveZeroModifier)
		return;

	bIdentified = true;
	ConstructItemName();
	if (Instigator != None && PlayerController(Instigator.Controller) != None)
		PlayerController(Instigator.Controller).ReceiveLocalizedMessage(class'IdentifyMessage', 0,,, self);
	if (ModifiedWeapon.OverlayMaterial == None)
		SetOverlayMaterial(ModifierOverlay, -1, true);
}

simulated function ConstructItemName()
{
	if (Modifier > 0)
		ItemName = PrefixPos$ModifiedWeapon.ItemName$PostfixPos@"+"$Modifier;
	else if (Modifier < 0)
		ItemName = PrefixNeg$ModifiedWeapon.ItemName$PostfixNeg@Modifier;
	else
		ItemName = PrefixPos$ModifiedWeapon.ItemName$PostfixPos;
}

//return true to allow player to have w
function bool AllowRPGWeapon(tfweapon w)
{
	if (Class == w.Class && ModifiedWeapon.Class == w.ModifiedWeapon.Class && Modifier >= w.Modifier)
		return false;

	return true;
}

//adjust damage to the enemies of the wielder of this weapon
function AdjustTargetDamage(out int Damage, Actor Victim, vector HitLocation, out vector Momentum, class<DamageType> DamageType);

//FIXME compatibility hack
function NewAdjustTargetDamage(out int Damage, int OriginalDamage, Actor Victim, vector HitLocation, out vector Momentum, class<DamageType> DamageType)
{
	AdjustTargetDamage(Damage, Victim, HitLocation, Momentum, DamageType);
}

defaultproperties
{
    bDoAmmoRegen=True
    StationDmgModifier=1
    AmmoRegenAmount(0)=1
    AmmoRegenAmount(1)=1
    SkillCost=1
}
